home *** CD-ROM | disk | FTP | other *** search
- From: dfs@doe.carleton.ca (David F. Skoll)
- Newsgroups: comp.sources.misc
- Subject: v17i005: remind - A replacement for calendar, Part03/04
- Message-ID: <1991Feb19.162824.16254@sparky.IMD.Sterling.COM>
- Date: 19 Feb 91 16:28:24 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: f88af471 4e687c5d 9416a1a1 516dee49
-
- Submitted-by: David F. Skoll <dfs@doe.carleton.ca>
- Posting-number: Volume 17, Issue 5
- Archive-name: remind/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 3 (of 4)."
- # Contents: cache.c dosubst.c files.c globals.h init.c omits.c
- # test.rem timed.c
- # Wrapped by kent@sparky on Tue Feb 19 10:16:40 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'cache.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cache.c'\"
- else
- echo shar: Extracting \"'cache.c'\" \(4966 characters\)
- sed "s/^X//" >'cache.c' <<'END_OF_FILE'
- X/***************************************************************/
- X/* */
- X/* CACHE.C */
- X/* */
- X/* Contains routines for caching reminder file to improve */
- X/* calendar performance. */
- X/* */
- X/* By David Skoll - 15 November 1990 */
- X/***************************************************************/
- X
- X#include <stdio.h>
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#include <string.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X#include "cache.h"
- X
- X/* Define a cached line */
- Xtypedef struct cached_line {
- X char *text;
- X struct cached_line *next;
- X} Centry;
- X
- XCentry Cache, *Current;
- X
- Xstatic int CacheDone, CacheFailed;
- X
- X/***************************************************************/
- X/* */
- X/* InitCache */
- X/* */
- X/* Initializes the caching system. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid InitCache(void)
- X#else
- Xvoid InitCache()
- X#endif
- X{
- X CacheDone = 0;
- X CacheFailed = 0;
- X Cache.next = NULL;
- X Current = &Cache;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* GetLine */
- X/* */
- X/* This function either reads a line from the file, or gets */
- X/* it from memory if it is cached. */
- X/* */
- X/* Returns 0 if more data to be read; otherwise, non-zero. */
- X/* */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint GetLine(void)
- X#else
- Xint GetLine()
- X#endif
- X{
- X int ret;
- X Token tok;
- X char *s;
- X Centry *c;
- X
- X if (CacheFailed) return ReadLine();
- X
- X if (!CacheDone) {
- X ret = ReadLine();
- X if (ret) {
- X CacheDone = 1;
- X strcpy(FileName, "* cache *");
- X CurLine = 0;
- X return ret;
- X }
- X /* Check if we should cache this line */
- X
- X s = Line;
- X tok = ParseToken(&s);
- X if (tok.type == Clear_t || tok.type == Push_t ||
- X tok.type == Pop_t || tok.type == Rem_t || tok.type == Omit_t) {
- X c = (Centry *) malloc(sizeof(Centry));
- X if (c == NULL) {
- X CacheFailed = 1;
- X DestroyCache();
- X return 0;
- X }
- X c->text = (char *) malloc(strlen(Line)+1);
- X if (c->text == NULL) {
- X CacheFailed = 1;
- X DestroyCache();
- X free(c);
- X return 0;
- X }
- X /* Insert the cache entry */
- X c->next = NULL;
- X strcpy(c->text, Line);
- X Current->next = c;
- X Current = c;
- X }
- X return ret;
- X } else { /* Over here, we've finished caching, so just return the line */
- X if (Current == NULL) return 1;
- X else {
- X strcpy(Line, Current->text);
- X Current = Current->next;
- X return 0;
- X }
- X }
- X}
- X/***************************************************************/
- X/* */
- X/* ResetCache */
- X/* Reset the cache to beginning, or reopen file if caching */
- X/* failed. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid ResetCache(void)
- X#else
- Xvoid ResetCache()
- X#endif
- X{
- X /* Reset the OMIT context */
- X ClearOmitContext();
- X
- X /* Get rid of any spurious stacked OMIT contexts */
- X FreeStackedOmits();
- X
- X if (CacheFailed) OpenFile(FileName);
- X else Current = Cache.next;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* DestroyCache */
- X/* Frees all memory used by the cache. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid DestroyCache(void)
- X#else
- Xvoid DestroyCache()
- X#endif
- X{
- X Centry *p = &Cache;
- X Centry *c = p->next;
- X
- X while (c) {
- X if (c->text) free(c->text);
- X p = c;
- X c = c->next;
- X free(p);
- X }
- X Cache.next = NULL;
- X}
- X
- END_OF_FILE
- if test 4966 -ne `wc -c <'cache.c'`; then
- echo shar: \"'cache.c'\" unpacked with wrong size!
- fi
- # end of 'cache.c'
- fi
- if test -f 'dosubst.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dosubst.c'\"
- else
- echo shar: Extracting \"'dosubst.c'\" \(8427 characters\)
- sed "s/^X//" >'dosubst.c' <<'END_OF_FILE'
- X#include <ctype.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* DOSUBST.C */
- X/* */
- X/* Performs line substitution for reminders. */
- X/* */
- X/* If mode = 0, ignore %" escapes. */
- X/* If mode = 1, process %" escapes. If a RUN type reminder */
- X/* does not have %" escape, return the empty string. */
- X/* */
- X/***************************************************************/
- X
- Xstatic char TODAY[] = "today";
- Xstatic char TOMORROW[] = "tomorrow";
- X
- X#ifdef __STDC__
- Xint DoSubst(char *src, char *dst, int d, int m, int y, int jul, enum Token_t t, int tim, int mode)
- X#else
- Xint DoSubst(src, dst, d, m, y, jul, t, tim, mode)
- X char *src;
- X char *dst;
- X int d;
- X int m;
- X int y;
- X int jul;
- X enum Token_t t;
- X int tim;
- X int mode;
- X#endif
- X{
- X int diff = jul - JulianToday;
- X char c;
- X char *od, *s;
- X int wkday = jul % 7;
- X char *plu, *pm;
- X int curtim = (int) (SystemTime() / 60);
- X int done;
- X int h;
- X int hh;
- X int min;
- X int tdiff;
- X int adiff, mdiff, hdiff;
- X char *mplu, *hplu, *when;
- X
- X if (mode == 1) {
- X s = src;
- X od = src;
- X while (*s) {
- X if (*s == '%' && *(s+1) == '\"') {
- X src = s+2;
- X break;
- X }
- X s++;
- X }
- X if (src == od && t == Run_t) {
- X *dst = 0;
- X return 0;
- X }
- X if (*src == '%' && *(src+1) == '\"') {
- X *dst = 0;
- X return 0;
- X }
- X if (tim != -1) {
- X sprintf(dst, "%02d:%02d ", (tim / 60), (tim % 60));
- X dst += strlen(dst);
- X }
- X }
- X
- X if (tim == -1) tim = curtim;
- X tdiff = tim - curtim;
- X adiff = ABS(tdiff);
- X mdiff = adiff % 60;
- X hdiff = adiff / 60;
- X mplu = (mdiff == 1 ? "" : "s");
- X hplu = (hdiff == 1 ? "" : "s");
- X when = (tdiff < 0 ? "ago" : "from now");
- X
- X h = tim / 60;
- X min = tim % 60;
- X
- X if (h >= 12) pm = "pm"; else pm = "am";
- X if (h == 12) hh = 12; else hh = h % 12;
- X
- X *dst = 0;
- X
- X switch(d) {
- X case 1:
- X case 21:
- X case 31: plu = "st"; break;
- X
- X case 2:
- X case 22: plu = "nd"; break;
- X
- X case 3:
- X case 23: plu = "rd"; break;
- X
- X default: plu = "th"; break;
- X }
- X
- X
- X while (c = *src++) {
- X if (c == '\n') continue;
- X else if (c != '%') { *dst++ = c; *dst = 0; }
- X else {
- X od = dst;
- X c = *src++;
- X done = 0;
- X if (diff <= 1) {
- X switch(upper(c)) {
- X case 'A':
- X case 'B':
- X case 'C':
- X case 'E':
- X case 'F':
- X case 'G':
- X case 'H':
- X case 'I':
- X case 'J':
- X case 'K':
- X case 'L':
- X case 'U':
- X case 'V': sprintf(dst, "%s", (diff ? TOMORROW : TODAY));
- X dst += strlen(dst);
- X done = 1;
- X break;
- X
- X default: done = 0;
- X }
- X }
- X
- X if (!done) switch(upper(c)) {
- X case 0: *dst = 0; return 0;
- X
- X case '\"': if (mode == 1) {
- X *dst = 0;
- X return 0;
- X }
- X break;
- X
- X case 'A':
- X sprintf(dst, "on %s, %d %s, %d", DayName[wkday], d,
- X MonthName[m], y);
- X dst += strlen(dst);
- X break;
- X
- X case 'B':
- X sprintf(dst, "in %d days' time", diff);
- X dst += strlen(dst);
- X break;
- X
- X case 'C':
- X sprintf(dst, "on %s", DayName[wkday]);
- X dst += strlen(dst);
- X break;
- X
- X case 'D':
- X sprintf(dst, "%d", d);
- X dst += strlen(dst);
- X break;
- X
- X case 'E':
- X sprintf(dst, "on %02d/%02d/%04d", d, m+1, y);
- X dst += strlen(dst);
- X break;
- X
- X case 'F':
- X sprintf(dst, "on %02d/%02d/%04d", m+1, d, y);
- X dst += strlen(dst);
- X break;
- X
- X case 'G':
- X sprintf(dst, "on %s, %d %s", DayName[wkday], d, MonthName[m]);
- X dst += strlen(dst);
- X break;
- X
- X case 'H':
- X sprintf(dst, "on %02d/%02d", d, m+1);
- X dst += strlen(dst);
- X break;
- X
- X case 'I':
- X sprintf(dst, "on %02d/%02d", m+1, d);
- X dst += strlen(dst);
- X break;
- X
- X case 'J':
- X sprintf(dst, "on %s, %s %d%s, %d", DayName[wkday],
- X MonthName[m], d, plu, y);
- X dst += strlen(dst);
- X break;
- X
- X case 'K':
- X sprintf(dst, "on %s, %s %d%s", DayName[wkday],
- X MonthName[m], d, plu);
- X dst += strlen(dst);
- X break;
- X
- X case 'L':
- X sprintf(dst, "on %04d/%02d/%02d", y, m+1, d);
- X dst += strlen(dst);
- X break;
- X
- X case 'M':
- X sprintf(dst, "%s", MonthName[m]);
- X dst += strlen(dst);
- X break;
- X
- X case 'N':
- X sprintf(dst, "%d", m+1);
- X dst += strlen(dst);
- X break;
- X
- X case 'O':
- X if (RealToday == JulianToday) sprintf(dst, " (today)");
- X dst += strlen(dst);
- X break;
- X
- X case 'P':
- X sprintf(dst, (diff == 1 ? "" : "s"));
- X dst += strlen(dst);
- X break;
- X
- X case 'Q':
- X sprintf(dst, (diff == 1 ? "'s" : "s'"));
- X dst += strlen(dst);
- X break;
- X
- X case 'R':
- X sprintf(dst, "%02d", d);
- X dst += strlen(dst);
- X break;
- X
- X case 'S':
- X sprintf(dst, plu);
- X dst += strlen(dst);
- X break;
- X
- X case 'T':
- X sprintf(dst, "%02d", m+1);
- X dst += strlen(dst);
- X break;
- X
- X case 'U':
- X sprintf(dst, "on %s, %d%s %s, %d", DayName[wkday], d,
- X plu, MonthName[m], y);
- X dst += strlen(dst);
- X break;
- X
- X case 'V':
- X sprintf(dst, "on %s, %d%s %s", DayName[wkday], d, plu,
- X MonthName[m]);
- X dst += strlen(dst);
- X break;
- X
- X case 'W':
- X sprintf(dst, DayName[wkday]);
- X dst += strlen(dst);
- X break;
- X
- X case 'X':
- X sprintf(dst, "%d", diff);
- X dst += strlen(dst);
- X break;
- X
- X case 'Y':
- X sprintf(dst, "%d", y);
- X dst += strlen(dst);
- X break;
- X
- X case 'Z':
- X sprintf(dst, "%d", y % 100);
- X dst += strlen(dst);
- X break;
- X
- X case '1':
- X if (tdiff == 0)
- X sprintf(dst, "now");
- X else if (hdiff == 0)
- X sprintf(dst, "%d minute%s %s", mdiff, mplu, when);
- X else if (mdiff == 0)
- X sprintf(dst, "%d hour%s %s", hdiff, hplu, when);
- X else
- X sprintf(dst, "%d hour%s and %d minute%s %s", hdiff, hplu, mdiff, mplu, when);
- X dst += strlen(dst);
- X break;
- X
- X case '2':
- X sprintf(dst, "at %d:%02d%s", hh, min, pm);
- X dst += strlen(dst);
- X break;
- X
- X case '3': sprintf(dst, "at %02d:%02d", h, min);
- X dst += strlen(dst);
- X break;
- X
- X case '4': sprintf(dst, "%d", tdiff);
- X dst += strlen(dst);
- X break;
- X
- X case '5': sprintf(dst, "%d", adiff);
- X dst += strlen(dst);
- X break;
- X
- X case '6': sprintf(dst, when);
- X dst += strlen(dst);
- X break;
- X
- X case '7': sprintf(dst, "%d", hdiff);
- X dst += strlen(dst);
- X break;
- X
- X case '8': sprintf(dst, "%d", mdiff);
- X dst += strlen(dst);
- X break;
- X
- X case '9': sprintf(dst, mplu);
- X dst += strlen(dst);
- X break;
- X
- X case '0': sprintf(dst, hplu);
- X dst += strlen(dst);
- X break;
- X
- X case '!': sprintf(dst, (tdiff >= 0 ? "is" : "was"));
- X dst += strlen(dst);
- X break;
- X
- X case '_': *dst++ = '\n'; *dst = 0;
- X break;
- X
- X default:
- X *dst++ = c;
- X *dst = 0;
- X }
- X if (isupper(c)) *od = upper(*od);
- X }
- X }
- X if (t == Msg_t && mode == 0) *dst++ = '\n';
- X *dst = 0;
- X return 0;
- X}
- END_OF_FILE
- if test 8427 -ne `wc -c <'dosubst.c'`; then
- echo shar: \"'dosubst.c'\" unpacked with wrong size!
- fi
- # end of 'dosubst.c'
- fi
- if test -f 'files.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'files.c'\"
- else
- echo shar: Extracting \"'files.c'\" \(8388 characters\)
- sed "s/^X//" >'files.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X#include <string.h>
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#ifndef UNIX
- X#include <dos.h>
- X#endif
- X#include <fcntl.h>
- X#ifdef UNIX
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <time.h>
- X#endif
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X#ifdef __STDC__
- Xstatic int PopFile(void);
- X#else
- Xstatic int PopFile();
- X#endif
- X
- X/***************************************************************/
- X/* */
- X/* FILES.C */
- X/* */
- X/* All the routines for opening initial file, getting */
- X/* and settting initial file's date, closing files, */
- X/* handling INCLUDE commands, etc. */
- X/* */
- X/***************************************************************/
- X
- X/* Define the structure for saving info about a file */
- Xtypedef struct {
- X long offset;
- X int curline;
- X char *name;
- X} FileSave;
- X
- X#define MAXINCLUDE 10
- X/* Set up array of MAXINCLUDE file save areas */
- Xstatic FileSave stack[MAXINCLUDE];
- Xstatic int SP;
- X
- Xstatic FILE *fp;
- X
- X/***************************************************************/
- X/* */
- X/* OpenFile */
- X/* */
- X/* Open the named file, initialize stack, get file date. */
- X/* If there's a problem, print an error msg and die. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid OpenFile(char *s)
- X#else
- Xvoid OpenFile(s)
- X char *s;
- X
- X#endif
- X{
- X unsigned date, time;
- X#ifndef UNIX
- X unsigned handle;
- X#endif
- X int d, m, y;
- X#ifndef UNIX
- X
- X /* Get the file's modification date */
- X if(_dos_open(s, O_RDONLY, &handle)) {
- X fprintf(stderr, "remind: Can't open %s.\n", s);
- X exit(1);
- X#else
- X struct stat t;
- X struct tm *t1;
- X
- X /* Get the file's access date */
- X if (stat(s, &t)) {
- X fprintf(stderr, "remind: Can't find file %s.\n", s);
- X exit(1);
- X#endif
- X }
- X#ifndef UNIX
- X _dos_getftime(handle, &date, &time);
- X d = date & 0x1F;
- X m = (date >> 5) & 0xF;
- X y = (date >> 9) + 1980;
- X#else
- X t1 = localtime(&(t.st_atime));
- X#endif
- X
- X#ifndef UNIX
- X if (y < BASE) LastRun = 0; else LastRun = Julian(d, m-1, y);
- X _dos_close(handle);
- X#else
- X y = t1->tm_year + 1900;
- X m = t1->tm_mon;
- X d = t1->tm_mday;
- X
- X if (y < BASE) LastRun = 0; else LastRun = Julian(d, m, y);
- X#endif
- X fp = fopen(s, "r");
- X if (fp == NULL) {
- X fprintf(stderr, "remind: Can't open %s.\n", s);
- X exit(1);
- X }
- X
- X CurLine = 0;
- X strcpy(FileName, s);
- X SP = 0;
- X
- X return;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* DoInclude */
- X/* */
- X/* Push the state of the current file and open a new file. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid DoInclude(char **s)
- X#else
- Xvoid DoInclude(s)
- X char **s;
- X
- X#endif
- X{
- X Token tok;
- X tok = ParseToken(s);
- X
- X /* First, check if there's room on the stack */
- X if (SP == MAXINCLUDE) {
- X Eprint("Too many levels of INCLUDE\n");
- X return;
- X }
- X
- X /* Save current data */
- X#ifndef UNIX
- X stack[SP].offset = ftell(fp) - 1L;
- X#else
- X stack[SP].offset = ftell(fp);
- X#endif
- X stack[SP].curline = CurLine;
- X stack[SP].name = (char *) malloc(strlen(FileName)+1);
- X if (stack[SP].name == NULL) {
- X Eprint("Out of memory for INCLUDE\n");
- X return;
- X }
- X strcpy(stack[SP].name, FileName);
- X
- X SP++;
- X
- X /* Close the current file */
- X fclose(fp);
- X
- X /* Open the new file */
- X fp = fopen(tok.str, "r");
- X if (fp == NULL) {
- X Eprint("Can't open %s for INCLUDE\n", tok.str);
- X PopFile();
- X return;
- X }
- X if (Debug || Purge) {
- X Eprint("INCLUDING file %s\n", tok.str);
- X }
- X
- X /* Set the global variables */
- X CurLine = 0;
- X strcpy(FileName, tok.str);
- X return;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* PopFile */
- X/* */
- X/* Pop to the previous file, if there is one. Return 0 for */
- X/* OK, non-zero for no more files. If we can't pop back */
- X/* to a file, print an error message and die. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xstatic int PopFile(void)
- X#else
- Xstatic int PopFile()
- X#endif
- X{
- X#ifndef UNIX
- X unsigned handle, date, time;
- X struct dostime_t t;
- X#endif
- X
- X if (fp) fclose(fp);
- X#ifndef UNIX
- X if (!SP) {
- X if (!Debug && !Purge && (JulianToday == RealToday)) {
- X if (_dos_open(FileName, O_RDONLY, &handle)) {
- X fprintf(stderr, "Could not reset date of %s\n", FileName);
- X return 1;
- X }
- X _dos_gettime(&t);
- X date = CurDay;
- X date |= (CurMon + 1) << 5;
- X date |= (CurYear - 1980) << 9;
- X time = t.second / 2;
- X time |= t.minute << 5;
- X time |= t.hour << 11;
- X _dos_setftime(handle, date, time);
- X }
- X return 1;
- X }
- X
- X#else
- X if (!SP) return -1;
- X
- X#endif
- X SP--;
- X fp = fopen(stack[SP].name, "r");
- X if (fp == NULL) {
- X Eprint("Argh! Can't return to %s from INCLUDE file %s\n", stack[SP].name, FileName);
- X exit(1);
- X }
- X#ifndef UNIX
- X if (fseek(fp, stack[SP].offset, SEEK_SET)) {
- X#else
- X if (fseek(fp, stack[SP].offset, 0)) {
- X#endif
- X Eprint("Argh! Can't fseek %s after returning from INCLUDE file %s\n", stack[SP].name, FileName);
- X exit(1);
- X }
- X
- X if (Debug || Purge) {
- X Eprint("Returning to file %s\n", stack[SP].name);
- X }
- X CurLine = stack[SP].curline;
- X strcpy(FileName, stack[SP].name);
- X free(stack[SP].name);
- X return 0;
- X}
- X/***************************************************************/
- X/* */
- X/* ReadLine */
- X/* */
- X/* Reads a line from the file. If EOF, pops to previous file */
- X/* if there was one. Returns 0 if more input, non-zero */
- X/* if no more input. Updates CurLine. */
- X/* */
- X/***************************************************************/
- Xint ReadLine()
- X{
- X int done = 0;
- X int len;
- X
- X Fresh = 1;
- X while (!done) {
- X CurLine++;
- X if (fgets(Line, 512, fp) == NULL) {
- X if (ferror(fp)) Eprint("Error reading %s\n", FileName);
- X if (PopFile()) return 1;
- X } else {
- X len = strlen(Line);
- X /* Remove the newline */
- X if (*Line && (*(Line + len-1)=='\n')) {
- X *(Line + strlen(Line)-1) = 0;
- X len--;
- X }
- X done = 1;
- X while(*Line && (*(Line + len-1) == '\\') && len<512) {
- X *(Line + len-1) = '\n';
- X if (fgets(Line+len, 512-len,fp) == NULL) {
- X *(Line + len) = 0;
- X break;
- X }
- X
- X CurLine++;
- X len = strlen(Line);
- X /* Remove the newline */
- X if (*Line && (*(Line + len-1)=='\n')) {
- X *(Line + strlen(Line)-1) = 0;
- X len--;
- X }
- X }
- X }
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* TopLevel - Returns 1 if current file is top level, 0 */
- X/* if it is INCLUDEd. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint TopLevel(void) { return (SP == 0); }
- X#else
- Xint TopLevel()
- X{
- X return (SP == 0);
- X}
- X#endif
- END_OF_FILE
- if test 8388 -ne `wc -c <'files.c'`; then
- echo shar: \"'files.c'\" unpacked with wrong size!
- fi
- # end of 'files.c'
- fi
- if test -f 'globals.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'globals.h'\"
- else
- echo shar: Extracting \"'globals.h'\" \(1469 characters\)
- sed "s/^X//" >'globals.h' <<'END_OF_FILE'
- X/***************************************************************/
- X/* */
- X/* GLOBALS.H */
- X/* */
- X/* Global variables for REMIND. */
- X/* */
- X/* By David Skoll - 30 Sept. 1990 */
- X/* */
- X/***************************************************************/
- X
- Xextern char *MonthName[];
- Xextern char *DayName[];
- Xextern Token keywd[];
- Xextern int MonthDays[];
- Xextern int MonthIndex[2][12];
- Xextern int FullOmitArray[];
- Xextern int PartOmitArray[];
- Xextern char Line[];
- Xextern char WorkBuf[];
- Xextern char TmpBuf[];
- Xextern char Fresh;
- Xextern char Purge;
- Xextern char Debug;
- Xextern char Verbose;
- Xextern char Next;
- Xextern char FileName[];
- Xextern int CurLine;
- Xextern int NumEmitted;
- Xextern int NumRem;
- Xextern int NumFullOmit;
- Xextern int NumPartOmit;
- Xextern int JulianToday;
- Xextern int LastRun;
- Xextern int CurYear;
- Xextern int CurMon;
- Xextern int CurDay;
- Xextern char Banner[];
- Xextern int RealToday;
- Xextern char IgRun;
- Xextern char IgOnce;
- Xextern int NumAtsQueued;
- Xextern char QueueAts;
- Xextern char PrintAts;
- Xextern int Calendar;
- Xextern int CalTime;
- Xextern int CalWidth;
- Xextern int SimpleCalendar;
- END_OF_FILE
- if test 1469 -ne `wc -c <'globals.h'`; then
- echo shar: \"'globals.h'\" unpacked with wrong size!
- fi
- # end of 'globals.h'
- fi
- if test -f 'init.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'init.c'\"
- else
- echo shar: Extracting \"'init.c'\" \(6305 characters\)
- sed "s/^X//" >'init.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X#include <string.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X#define PATCHLEVEL 0
- X
- Xstatic char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
- Xstatic char DPCMsg[] = "Calendar overrides Debug and Purge options.\n";
- Xstatic char NMsg[] = "Next overrides Calendar, Debug and Purge options.\n";
- X
- X/***************************************************************/
- X/* */
- X/* void initialize(int argc, char *argv[]) */
- X/* */
- X/* Reads command line options, sets appropriate flags */
- X/* and FileName. Also exits with error if invoked */
- X/* incorrectly. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid initialize(int argc, char *argv[])
- X#else
- Xvoid initialize(argc, argv)
- X int argc;
- X char *argv[];
- X#endif
- X{
- X int i;
- X char *s;
- X int d, m, y, t;
- X Token tok;
- X
- X Debug = 0;
- X Purge = 0;
- X Verbose = 0;
- X IgOnce = 0;
- X IgRun = 0;
- X Calendar = 0;
- X Next = 0;
- X PrintAts = 1;
- X QueueAts = 1;
- X CalWidth = 10;
- X SimpleCalendar = 0;
- X
- X if(argc == 1) {
- X fprintf(stderr, "\nREMIND 2.3 Patch Level %d (C) 1990, 1991 by David Skoll.\n\n", PATCHLEVEL);
- X#ifdef UNIX
- X fprintf(stderr, "Usage: remind [-n | -d | -p | -c# [-w# | -s]] [-voraq] filename [date]\n\n");
- X#else
- X fprintf(stderr, "Usage: remind [-n | -d | -p | -c# [-w# | -s]] [-vor] filename [date]\n\n");
- X#endif
- X fprintf(stderr, "-n Output next occurrence of reminders in simple format\n");
- X fprintf(stderr, "-d Debug reminder file\n-p Purge reminder file\n");
- X fprintf(stderr, "-c# Produce calendar for # months\n");
- X fprintf(stderr, "-w# Make calendar # columns wide\n");
- X fprintf(stderr, "-s Produce simple calendar listing (used with -c)\n");
- X fprintf(stderr, "-v Verbose messages\n-o Ignore ONCE directives\n");
- X fprintf(stderr, "-r Ignore RUN directives\n");
- X#ifdef UNIX
- X fprintf(stderr, "-a Do not trigger current AT reminders in foreground\n");
- X fprintf(stderr, "-q Do not queue current AT reminders\n\n");
- X#endif
- X exit(1);
- X }
- X
- X i = 1;
- X s = argv[i];
- X
- X /* Process options */
- X while (*s == '-') {
- X while (*++s) {
- X switch(upper(*s)) {
- X
- X case 'N': Next = 1;
- X if (Calendar || Debug || Purge) {
- X Calendar = Debug = Purge = 0;
- X fprintf(stderr, NMsg);
- X }
- X break;
- X
- X case 'P': Purge = 1;
- X if (Next) {
- X Calendar = Debug = Purge = 0;
- X fprintf(stderr, NMsg);
- X }
- X if (Calendar) {
- X Debug = Purge = 0;
- X fprintf(stderr, DPCMsg);
- X }
- X if (Debug) {
- X Debug = 0;
- X fprintf(stderr, DPMsg);
- X }
- X break;
- X
- X case 'D': Debug = 1;
- X if (Next) {
- X Calendar = Debug = Purge = 0;
- X fprintf(stderr, NMsg);
- X }
- X if (Calendar) {
- X Debug = Purge = 0;
- X fprintf(stderr, DPCMsg);
- X }
- X if (Purge) {
- X Debug = 0;
- X fprintf(stderr, DPMsg);
- X }
- X break;
- X
- X case 'C': Calendar = 1;
- X if (Next) {
- X Calendar = Debug = Purge = 0;
- X fprintf(stderr, NMsg);
- X }
- X if (Debug || Purge) {
- X Debug = Purge = 0;
- X fprintf(stderr, DPCMsg);
- X }
- X t = atoi(s + 1);
- X if (t > 0 && t <= 12) Calendar = t;
- X /* Skip remaining chars on this option */
- X while (*++s) ;
- X s--;
- X break;
- X
- X case 'W': CalWidth = (atoi(s+1)-9)/7;
- X if (CalWidth < 10) CalWidth = 10;
- X if (CalWidth > 40) CalWidth = 40;
- X while (*++s) ;
- X s--;
- X break;
- X
- X case 'S': SimpleCalendar = 1; break;
- X
- X case 'V': Verbose = 1; break;
- X
- X case 'O': IgOnce = 1; break;
- X
- X case 'R': IgRun = 1; break;
- X#ifdef UNIX
- X case 'A': PrintAts = 0; break;
- X
- X case 'Q': QueueAts = 0; break;
- X#endif
- X default: fprintf(stderr, "Unknown option '%c' ignored.\n", *s);
- X }
- X }
- X i++;
- X if (i >= argc) {
- X fprintf(stderr, "Missing filename - type 'remind' for usage information.\n");
- X exit(1);
- X }
- X s = argv[i];
- X }
- X
- X /* Set FileName */
- X strcpy(FileName, argv[i++]);
- X
- X /* Get date, if supplied */
- X if (i < argc) {
- X *WorkBuf = 0;
- X while (i < argc) {
- X strcat(WorkBuf, argv[i++]);
- X strcat(WorkBuf, " ");
- X }
- X /* Parse the date */
- X d = m = y = -1;
- X tok.type = Unknown_t;
- X s = WorkBuf;
- X while (tok.type != Eol_t) {
- X tok = ParseToken(&s);
- X switch(tok.type) {
- X
- X case Eol_t: break;
- X
- X case Year_t: if (y == -1)
- X y = tok.val;
- X else {
- X fprintf(stderr, "Year specified twice!\n");
- X exit(1);
- X }
- X break;
- X
- X case Month_t: if (m == -1)
- X m = tok.val;
- X else {
- X fprintf(stderr, "Month specified twice!\n");
- X exit(1);
- X }
- X break;
- X
- X case Day_t: if (d == -1)
- X d = tok.val;
- X else {
- X fprintf(stderr, "Day specified twice!\n");
- X exit(1);
- X }
- X break;
- X
- X default: fprintf(stderr, "Illegal token %s on command line.\n", tok.str);
- X exit(1);
- X
- X }
- X }
- X
- X if (d == -1 || m == -1 || y == -1) {
- X fprintf(stderr, "Date on command line must be fully specified.\n");
- X exit(1);
- X }
- X if (CheckDate(d, m, y)) {
- X fprintf(stderr, "Illegal date on command line.\n");
- X exit(1);
- X }
- X
- X CurDay = d;
- X CurMon = m;
- X CurYear = y;
- X JulianToday = Julian(d, m, y);
- X }
- X OpenFile(FileName);
- X if (Debug) {
- X FromJulian(LastRun, &d, &m, &y);
- X#ifndef UNIX
- X fprintf(stderr, "\nFile %s last modified on %s, %d %s, %d\n", FileName,
- X#else
- X fprintf(stderr, "\nFile %s last accessed on %s, %d %s, %d\n", FileName,
- X#endif
- X DayName[LastRun % 7], d, MonthName[m], y);
- X }
- X return;
- X}
- END_OF_FILE
- if test 6305 -ne `wc -c <'init.c'`; then
- echo shar: \"'init.c'\" unpacked with wrong size!
- fi
- # end of 'init.c'
- fi
- if test -f 'omits.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'omits.c'\"
- else
- echo shar: Extracting \"'omits.c'\" \(10630 characters\)
- sed "s/^X//" >'omits.c' <<'END_OF_FILE'
- X/***************************************************************/
- X/* */
- X/* OMITS.C */
- X/* */
- X/* By David Skoll - 12 February 1991 */
- X/* */
- X/* Handle all code related to global OMITs */
- X/* */
- X/***************************************************************/
- X#include <stdio.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X
- X#include "defines.h"
- X#include "protos.h"
- X#include "globals.h"
- X
- X/* Define an OMIT stack buffer */
- Xtypedef struct omit_stack {
- X struct omit_stack *next;
- X int NumFullOmit;
- X int NumPartOmit;
- X int Omits[1];
- X} OmitBuffer;
- X
- X/* Variables that we only want visible here */
- Xstatic OmitBuffer *OmitStack = (OmitBuffer *) NULL;
- X
- X/***************************************************************/
- X/* */
- X/* int DoGlobalOmit(char **s) */
- X/* */
- X/* Add an entry to the global ommissions array. Either */
- X/* a fully-specified date, or a mm-yy type date. */
- X/* Return 0 if OK, -1 if date is in past, -2 if problem. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint DoGlobalOmit(char **s)
- X#else
- Xint DoGlobalOmit(s)
- X char **s;
- X#endif
- X{
- X int d = -1, m = -1, y = -1;
- X int omit;
- X int *ptr;
- X Token tok;
- X char *olds = *s;
- X
- X tok.type = Unknown_t;
- X while(tok.type != Eol_t && tok.type != Run_t && tok.type != Msg_t) {
- X tok = ParseToken(s);
- X switch (tok.type) {
- X case Year_t: y = tok.val; break;
- X case Month_t: m = tok.val; break;
- X case Day_t: d = tok.val; break;
- X
- X case Delta_t:
- X case Eol_t:
- X case Msg_t:
- X case Run_t: break;
- X default: Eprint("Invalid token '%s' for OMIT command.\n", tok.str);
- X return -2;
- X }
- X }
- X
- X if (d == -1 || m == -1 || CheckDate(d, m, y)) {
- X Eprint("Invalid date specification.\n");
- X return -2;
- X }
- X
- X if (y == -1) { /* Only mm-dd specified */
- X if (NumPartOmit == POMITSIZE) {
- X Eprint("Too many partially-specified OMITs.\n");
- X return -2;
- X }
- X omit = (m << 5) + d;
- X ptr = PartOmitArray + NumPartOmit;
- X NumPartOmit++;
- X while (ptr > PartOmitArray && *(ptr-1) > omit) {
- X *ptr = *(ptr-1);
- X ptr--;
- X }
- X *ptr = omit;
- X
- X /* Check if the bonehead already has it - if so, delete it */
- X if (ptr > PartOmitArray && *(ptr-1) == *ptr) {
- X if (Debug) Eprint("Duplicated partially-specified OMIT.\n");
- X NumPartOmit--;
- X while (ptr < NumPartOmit+PartOmitArray) {
- X *ptr = *(ptr + 1);
- X ptr++;
- X }
- X }
- X /* If we got a DELTA, a MSG or a RUN, then execute DoRem */
- X if (tok.type == Delta_t || tok.type == Run_t || tok.type == Msg_t)
- X return DoRem(&olds);
- X } else { /* All three specified */
- X if (NumFullOmit == FOMITSIZE) {
- X Eprint("Too many fully-specified OMITs.\n");
- X return -2;
- X }
- X omit = Julian(d, m, y);
- X
- X ptr = FullOmitArray + NumFullOmit;
- X NumFullOmit++;
- X while (ptr > FullOmitArray && *(ptr-1) > omit) {
- X *ptr = *(ptr-1);
- X ptr--;
- X }
- X *ptr = omit;
- X
- X /* Check if the bonehead already has it - if so, delete it */
- X if (ptr > FullOmitArray && *(ptr-1) == *ptr) {
- X if (Debug) Eprint("Duplicated fully-specified OMIT.\n");
- X NumFullOmit--;
- X while (ptr < NumFullOmit+FullOmitArray) {
- X *ptr = *(ptr + 1);
- X ptr++;
- X }
- X }
- X if (omit < JulianToday) {
- X if (Debug) Eprint("Omit has expired.\n");
- X return -1;
- X }
- X /* If we got a DELTA, a MSG or a RUN, then execute DoRem */
- X if (tok.type == Delta_t || tok.type == Run_t || tok.type == Msg_t)
- X return DoRem(&olds);
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* PushOmitContext */
- X/* */
- X/* Push the Global OMIT context onto a stack. */
- X/* */
- X/* Returns 0 for success, 1 for failure. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint PushOmitContext(void)
- X#else
- Xint PushOmitContext()
- X#endif
- X{
- X OmitBuffer *new = (OmitBuffer *) malloc( sizeof(OmitBuffer) +
- X (NumFullOmit + NumPartOmit - 1) * sizeof(int));
- X
- X if (!new) {
- X Eprint("Unable to allocate memory for PUSH-OMIT-CONTEXT.\n");
- X return 1;
- X }
- X
- X new->NumFullOmit = NumFullOmit;
- X new->NumPartOmit = NumPartOmit;
- X
- X CopyInts(FullOmitArray, &(new->Omits[0]), NumFullOmit);
- X CopyInts(PartOmitArray, &(new->Omits[NumFullOmit]), NumPartOmit);
- X
- X new->next = OmitStack;
- X OmitStack = new;
- X
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* PopOmitContext */
- X/* */
- X/* Restore the OMIT context from the stack. */
- X/* */
- X/* Returns 0 for success, 1 for failure. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint PopOmitContext(void)
- X#else
- Xint PopOmitContext()
- X#endif
- X{
- X
- X OmitBuffer *temp;
- X
- X if (!OmitStack) {
- X Eprint("No saved contexts for POP-OMIT-CONTEXT.\n");
- X return 1;
- X }
- X
- X NumFullOmit = OmitStack->NumFullOmit;
- X NumPartOmit = OmitStack->NumPartOmit;
- X
- X CopyInts(&(OmitStack->Omits[0]), FullOmitArray, NumFullOmit);
- X CopyInts(&(OmitStack->Omits[NumFullOmit]), PartOmitArray, NumPartOmit);
- X
- X temp = OmitStack->next;
- X free(OmitStack);
- X OmitStack = temp;
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* ClearOmitContext */
- X/* */
- X/* Get rid of all global OMITS. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid ClearOmitContext(void)
- X#else
- Xvoid ClearOmitContext()
- X#endif
- X{
- X NumFullOmit = NumPartOmit = 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* CopyInts */
- X/* */
- X/* Copy integer values from one array to another. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid CopyInts(int *from, int *to, int count)
- X#else
- Xvoid CopyInts(from, to, count)
- Xint *from, *to, count;
- X#endif
- X{
- X while (count--) *to++ = *from++;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FreeStackedOmits */
- X/* */
- X/* Get rid of all the stacked OMIT contexts */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid FreeStackedOmits(void)
- X#else
- Xvoid FreeStackedOmits()
- X#endif
- X{
- X OmitBuffer *current = OmitStack, *next;
- X
- X if (current && Debug) Eprint("Warning - more PUSH-OMIT-CONTEXTs than POP-OMIT-CONTEXTs\n");
- X
- X while (current) {
- X next = current->next;
- X free(current);
- X current = next;
- X }
- X
- X OmitStack = (OmitBuffer *) NULL;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* IsOmitted */
- X/* */
- X/* Returns non-zero if the julian date should be omitted, 0 */
- X/* otherwise. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint IsOmitted(int jul, int localomit)
- X#else
- Xint IsOmitted(jul, localomit)
- Xint jul, localomit;
- X#endif
- X{
- X int d, m, y;
- X
- X /* Check if we should omit because of local omit */
- X if (localomit & 1 << (jul % 7)) return 1;
- X
- X /* Check if we should omit because of fully-specified global omit */
- X if (NumFullOmit && my_bsearch(jul, FullOmitArray, NumFullOmit)) return 1;
- X
- X /* Check if we should omit because of partially-specified global omits */
- X if (NumPartOmit) {
- X FromJulian(jul, &d, &m, &y);
- X if (my_bsearch((m << 5)+d, PartOmitArray, NumPartOmit)) return 1;
- X }
- X
- X /* Looks cool - don't omit */
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* my_bsearch */
- X/* */
- X/* A simplified version of bsearch() for people whose library */
- X/* does not have the full version. This only works when */
- X/* searching a sorted array of integers. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint *my_bsearch(int key, int *array, int number)
- X#else
- Xint *my_bsearch(key, array, number)
- Xint key, *array, number;
- X#endif
- X{
- X int top = number - 1;
- X int bot = 0;
- X int mid;
- X
- X while (top >= bot) {
- X mid = (top+bot)/2;
- X if (*(array+mid) == key) return array+mid;
- X else if (*(array+mid) > key) top = mid-1;
- X else bot = mid+1;
- X }
- X
- X /* Oh, well - unsuccessful search. Return NULL */
- X return NULL;
- X}
- END_OF_FILE
- if test 10630 -ne `wc -c <'omits.c'`; then
- echo shar: \"'omits.c'\" unpacked with wrong size!
- fi
- # end of 'omits.c'
- fi
- if test -f 'test.rem' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'test.rem'\"
- else
- echo shar: Extracting \"'test.rem'\" \(2975 characters\)
- sed "s/^X//" >'test.rem' <<'END_OF_FILE'
- X# Test file for REMIND
- X#
- X# Use this file to test the date calculation routines
- X# of the REMIND program by typing:
- X#
- X# (UNIX version):
- X# remind -dv test.rem 16 FEB 1991 >& temp
- X#
- X# (DOS version):
- X# e2o remind -dv test.rem 16 FEB 1991 > temp
- X#
- X# and comparing the results with test.out.
- X#
- X# The only differences should be the date of last
- X# modification/access
- X
- X# Test each possible case of the basic reminders.
- X
- XREM MSG Every Day
- X
- XREM 18 MSG Every 18th
- XREM 15 MSG Every 15th
- X
- XREM Feb MSG February
- XREM Jan MSG January
- XREM March MSG March
- X
- XREM 13 Jan MSG 13 Jan
- XREM 15 Feb MSG 15 Feb
- XREM 28 Feb MSG 28 Feb
- XREM 29 Feb MSG 29 Feb
- XREM 5 Mar MSG 5 Mar
- X
- XREM 1990 MSG 1990
- XREM 1991 MSG 1991
- XREM 1992 MSG 1991
- X
- XREM 1 1990 MSG 1 1990
- XREM 29 1991 MSG 29 1991
- XREM 29 1992 MSG 29 1992
- XREM 16 1991 MSG 16 1991
- X
- XREM Jan 1990 MSG Jan 1990
- XREM Feb 1991 MSG Feb 1991
- XREM Dec 1991 MSG Dec 1991
- XREM May 1992 MSG May 1992
- X
- XREM 1 Jan 1991 MSG 1 Jan 1991
- XREM 16 Feb 1991 MSG 16 Feb 1991
- XREM 29 Dec 1992 MSG 29 Dec 1992
- X
- XREM Sun MSG Sun
- XREM Fri Sat Tue MSG Fri Sat Tue
- X
- XREM Sun 16 MSG Sun 16
- XREM Mon Tue Wed Thu Fri 1 MSG Mon Tue Wed Thu Fri 1
- X
- XREM Sun Feb MSG Sun Feb
- XREM Mon Tue March MSG Mon Tue March
- X
- XREM Sun 16 Feb MSG Sun 16 Feb
- XREM Mon Tue 10 March MSG Mon Tue 10 March
- X
- XREM Sat Sun 1991 MSG Sat Sun 1991
- XREM Mon Tue 1992 MSG Mon Tue 1992
- X
- XREM Sun 16 1991 MSG Sun 16 1991
- XREM Mon Tue Wed Thu Fri 1 1992 MSG Mon Tue Wed Thu Fri 1 1992
- X
- XREM Mon Feb 1991 MSG Mon Feb 1991
- XREM Tue Jan 1992 MSG Tue Jan 1992
- X
- XREM Sun Mon 16 Feb 1991 MSG Sun Mon 16 Feb 1991
- XREM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
- X
- X# Try some Backs
- XCLEAR-OMIT-CONTEXT
- XREM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
- XREM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
- X
- XOMIT 28 Feb
- XREM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
- XREM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun (28 Feb omitted)
- X
- XCLEAR-OMIT-CONTEXT
- X
- X# Try out UNTIL
- XREM Wed UNTIL 21 Feb 1991 MSG Wed UNTIL 21 Feb 1991
- X
- X# Try playing with the OMIT context
- X
- XOMIT 28 Feb 1991
- XREM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
- XREM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
- XREM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
- XREM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
- XREM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
- X
- XPUSH-OMIT-CONTEXT
- XCLEAR-OMIT-CONTEXT
- XREM 1 Mar -1 MSG 1 mar -1
- XREM 1 Mar --1 MSG 1 mar --1
- XREM 28 Feb BEFORE MSG 28 Feb BEFORE
- XREM 28 Feb SKIP MSG 28 Feb SKIP
- XREM 28 Feb AFTER MSG 28 Feb AFTER
- X
- XPOP-OMIT-CONTEXT
- XREM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
- XREM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
- XREM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
- XREM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
- XREM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
- X
- X
- XREM 13 March 1991 *1 UNTIL 19 March 1991 MSG 13-19 Mar 91
- X
- X# Test BACK
- XCLEAR-OMIT-CONTEXT
- XREM 18 Feb 1991 +1 MSG 18 Feb 1991 +1
- X
- XOMIT 17 Feb 1991
- XREM 18 Feb 1991 +1 MSG 18 Feb 1991 +1 (17Feb91 omitted)
- XREM 18 Feb 1991 ++1 MSG 18 Feb 1991 ++1 (17Feb91 omitted)
- X
- XCLEAR-OMIT-CONTEXT
- X
- END_OF_FILE
- if test 2975 -ne `wc -c <'test.rem'`; then
- echo shar: \"'test.rem'\" unpacked with wrong size!
- fi
- # end of 'test.rem'
- fi
- if test -f 'timed.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'timed.c'\"
- else
- echo shar: Extracting \"'timed.c'\" \(7484 characters\)
- sed "s/^X//" >'timed.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <signal.h>
- X#include <string.h>
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* TIMED.C */
- X/* */
- X/* Contains routines for triggering timed reminders */
- X/* */
- X/* By David Skoll - 12 Nov 1990 */
- X/* */
- X/* (C) 1990 by David Skoll */
- X/* */
- X/***************************************************************/
- X
- X/* Global pointer to AT reminders */
- X
- Xstatic AtEntry AtQueue =
- X{
- X 0, 0, 0, 0, Unknown_t, NULL, NULL
- X};
- X
- X/***************************************************************/
- X/* */
- X/* AddEntry */
- X/* */
- X/* Add an entry to the AT queue, keeping things sorted by */
- X/* trigger time. */
- X/* */
- X/* Returns 0 for success, nonzero for failure */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint AddEntry(AtEntry *e)
- X#else
- Xint AddEntry(e)
- XAtEntry *e;
- X#endif
- X{
- X AtEntry *current, *prev;
- X prev = &AtQueue;
- X current = prev->next;
- X while (current) {
- X if (e->firsttime < current->firsttime) {
- X prev->next = e;
- X e->next = current;
- X break;
- X } else {
- X prev = current;
- X current = prev->next;
- X }
- X }
- X if (!current) {
- X prev->next = e;
- X e->next = NULL;
- X }
- X}
- X
- X/***************************************************************/
- X/* */
- X/* DoAt */
- X/* Creates an entry for an At reminder, puts it on the queue */
- X/* Updates the global variable NumAtsQueued */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint DoAt(int tim, int tdelta, int trep, char *body, enum Token_t type)
- X#else
- Xint DoAt(tim, tdelta, trep, body, type)
- Xint tim, tdelta, trep;
- Xchar *body;
- Xenum Token_t type;
- X#endif
- X{
- X AtEntry *e;
- X int curtime;
- X
- X curtime = (int) (SystemTime() / 60);
- X
- X /* If the trigger time is in the past, don't add to the at queue */
- X if (tim < curtime) return 0;
- X
- X /* Allocate space for the entry */
- X e = (AtEntry *) malloc(sizeof(AtEntry));
- X if (e == (AtEntry *) NULL) {
- X Eprint("Can't malloc memory for AT!\n");
- X return 1;
- X }
- X e->text = malloc(strlen(body)+1);
- X if (e->text == NULL) {
- X Eprint("Can't malloc memory for body of AT!\n");
- X return 1;
- X }
- X strcpy(e->text, body);
- X
- X /* Find out the next trigger time */
- X e->firsttime = FindNextTriggerTime(tim, trep, tdelta, curtime);
- X e->repeat = trep;
- X e->type = type;
- X e->time = tim;
- X e->delta = tdelta;
- X AddEntry(e);
- X NumAtsQueued++;
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int FindNextTriggerTime */
- X/* */
- X/* Returns the next time a queued AT should be triggered. */
- X/* Returns -1 if the AT has expired. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint FindNextTriggerTime(int tim, int rep, int delta, int curtime)
- X#else
- Xint FindNextTriggerTime(tim, rep, delta, curtime)
- Xint tim, rep, delta, curtime;
- X#endif
- X{
- X int trigger = tim;
- X
- X if (delta <= 0)
- X if (trigger < curtime) return -1; else return trigger;
- X
- X trigger -= delta;
- X if (rep == -1) rep = delta;
- X
- X if (trigger < curtime) trigger += ((curtime - trigger) / rep) * rep;
- X if (trigger < curtime) trigger += rep;
- X if (trigger > tim) trigger = tim;
- X if (trigger < curtime) return -1; else return trigger;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* HandleQueuedAts */
- X/* */
- X/* Handles all the queued AT reminders. Sits in a sleep loop */
- X/* to trigger reminders. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid HandleQueuedAts(void)
- X#else
- Xvoid HandleQueuedAts()
- X#endif
- X{
- X AtEntry *e;
- X long TimeToSleep;
- X unsigned SleepTime;
- X long now;
- X
- X signal(SIGINT, SigIntHandler);
- X
- X while (e = AtQueue.next) {
- X now = SystemTime();
- X TimeToSleep = (long) e->firsttime * 60L - now;
- X if (TimeToSleep < 0L) TimeToSleep = 0L;
- X
- X /* Be paranoid and assume that unsigneds are only two bytes long -
- X therefore, do the sleeping in 30000-second chunks. */
- X
- X while (TimeToSleep) {
- X if (TimeToSleep > 30000L) SleepTime = 30000;
- X else SleepTime = (unsigned) TimeToSleep;
- X sleep(SleepTime);
- X TimeToSleep -= (long) SleepTime;
- X }
- X
- X /* Over here, we trigger the reminder */
- X DoSubst(e->text, WorkBuf, CurDay, CurMon, CurYear, JulianToday, e->type, e->time, 0);
- X if (e->type == Run_t) system(WorkBuf);
- X else printf("%s\n", WorkBuf);
- X
- X /* Remove the entry from the queue */
- X AtQueue.next = e->next;
- X
- X /* Check if this reminder should be re-triggered */
- X e->firsttime = FindNextTriggerTime(e->time, e->repeat,
- X e->delta, e->firsttime + 1);
- X
- X if (e->firsttime != -1) AddEntry(e);
- X else {
- X /* Not to be added - free the memory */
- X free(e->text);
- X free(e);
- X }
- X }
- X}
- X
- X/***************************************************************/
- X/* */
- X/* SigIntHandler */
- X/* */
- X/* For debugging purposes, when sent a SIGINT, we print the */
- X/* contents of the queue. */
- X/* */
- X/***************************************************************/
- Xvoid SigIntHandler()
- X{
- X AtEntry *e;
- X
- X printf("Contents of AT queue:\n");
- X
- X e = AtQueue.next;
- X while (e) {
- X printf("Trigger: %02d:%02d Activate: %02d:%02d Rep: %d Delta: %d\n",
- X e->time / 60, e->time % 60, e->firsttime / 60, e->firsttime % 60,
- X e->repeat, e->delta);
- X printf("Text: %s %s\n\n", ((e->type == Msg_t) ? "MSG" : "RUN"), e->text);
- X e = e->next;
- X }
- X printf("\n");
- X}
- END_OF_FILE
- if test 7484 -ne `wc -c <'timed.c'`; then
- echo shar: \"'timed.c'\" unpacked with wrong size!
- fi
- # end of 'timed.c'
- fi
- echo shar: End of archive 3 \(of 4\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-